package ganga.custodian.sensors;

import ganga.custodian.CustodianApplication;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.util.Log;

import java.sql.Timestamp;

/**
 * Класс обеспечивает работу с трёхосным акселерометром.
 * Умеет снимать показания и записывать их в БД
 * @author Apocrypha
 */
public class AccelerometerMonitor implements SensorEventListener {
	/**
	 * A three-axis accelerometer sensor that returns the current acceleration
	 * along three axes in m/s2. Записывает показания акселерометра
	 * 
	 * @author Apocrypha
	 * 
	 */
	private CustodianApplication application;
	
	//CalibrationRecordData 
	public boolean isRecording;
	public Timestamp recordStartedAt;
	public long sessionId;

	//public AccelerometerBuffer buffer;
	final int BUFFER_SIZE = 20000;
	AccelerometerData[] buffer;
	private int rowInBuffer;

	public AccelerometerMonitor(CustodianApplication application){
		this.application = application;
		isRecording = false;
		buffer = new AccelerometerData[BUFFER_SIZE];
		for(int i=0;i<BUFFER_SIZE;++i)
			buffer[i] = new AccelerometerData();
	}
	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		// TODO Auto-generated method stub
	}

	/**
     * Called when sensor values have changed.
     *
     * @param   event           The sensor event.
     */
	@Override
	public void onSensorChanged(SensorEvent event) {
		try {
            final float[] values = event.values;
            if (values.length < 3)
                return;

            int sensorType = event.sensor.getType();

            if (!isRecording)
				return;

            if (sensorType == Sensor.TYPE_ACCELEROMETER){
                //application.database.insertAcc(sessionId, getCurrentTimestamp(), values);
                //buffer.Add(getCurrentTimestamp(), values);
            	AccelerometerData data = buffer[rowInBuffer];
            	data.timestamp = System.currentTimeMillis();
            	data.eventTimestamp = event.timestamp;
            	data.ax = values[0];
            	data.ay = values[1];
            	data.az = values[2];
            	
            	++rowInBuffer;
            	if (rowInBuffer >= BUFFER_SIZE) 
            		rowInBuffer = 0;
            } 
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	public void startRecord(String position, String activity, String movement){
		if (isRecording) return;
		
		isRecording = true;
		rowInBuffer = 0;
		recordStartedAt = getCurrentTimestamp();
		sessionId = application.database.insertMeasurementSession(recordStartedAt, position, activity, movement);
	}
	public void stopRecord(){
		isRecording = false;
		long duration = getCurrentTimestamp().getTime() - recordStartedAt.getTime();
		application.database.updateMeasurementSession(sessionId, duration);
		application.database.close();
	}
	public void saveFromBuffer(){
		/*
		AccelerometerValuesBasket busketToSave;
		while (!buffer.isEmpty()) {
			Log.d("Save, buff size", Integer.toString(buffer.size()));
			synchronized (buffer) {
				busketToSave = buffer.poll();
			}

			for (AccelerometerData data : busketToSave.data) {
				application.database.insertAcc(sessionId, data);
			}
		}
		*/
		Log.d("Saving... ", Integer.toString(rowInBuffer));
		for (int i = 0; i < rowInBuffer; i++) {
			application.database.insertAcc(sessionId, buffer[i]);
		}
		rowInBuffer = 0;
		Log.d("Completed", Integer.toString(rowInBuffer));
	}
	public Timestamp getCurrentTimestamp() {
		return new Timestamp(System.currentTimeMillis());
	}
	public long getLongCurrentTimestamp() {
		return System.currentTimeMillis();
	}
}
